#ifdef linux

#include <iostream>
#include <thread>
#include <atomic>

#include "unix_client.h"
std::atomic_bool s_recv_thread_compate(false);
namespace network
{
client::client(const std::string& ip, const port_t port, recv_callback call) : m_addr(new address(ip, port))
{
    init(call);
}
client::client(const address& a, recv_callback call) : m_addr(new address(a))
{
    init(call);
}
void client::init(recv_callback call)
{
    if(call)
        m_callback = call;

    m_socket = -1;
    m_socket = socket( AF_INET, SOCK_STREAM, 0 );
    if(m_socket == -1)
        std::cout << "socket error!" << std::endl;
    
    auto saddr = to_sockaddr(m_addr);

    if(connect(m_socket, (struct sockaddr*)saddr, sizeof(*saddr)) == -1)
    {
        std::cout << "connect error!" << std::endl;
        m_socket = -1;
    }

    process_recv();
}
void client::process_recv()
{
    std::shared_ptr<std::thread> t(new std::thread([&] {
        s_recv_thread_compate = false;
        while(m_recv_run)
        {
            recv_callback call = nullptr;
            if(m_callback)
                call = m_callback;

            if(m_socket == -1)
                continue;

            char* buf = new char[BUF_SIZE + 1];
            memset(buf, 0, BUF_SIZE + 1);
            int r = 0;
            std::string result;
            do
            {
                r = recv(m_socket, buf, BUF_SIZE, 0);
                result += string(buf, r);
                std::cout << "recv size:" << r << std::endl;
            } while (r >= BUF_SIZE);

            if(call)
                call(result, m_socket);
        }
        s_recv_thread_compate = true;
    }));

    t->detach();
}
int client::send(const std::string& data)
{
    int len = 0;

    while(len < (int)data.length())
    {
        len += write(m_socket, (void*)data.c_str(), data.length());
    }

    return len;
}
client::~client()
{
    m_recv_run = false;
    while(!s_recv_thread_compate);

    close(m_socket);
    delete m_addr;
}
}
#endif